#include "iodefine.h"
#include "sl_types.h"
#include "sl_port.h"


////////////////////////////////////////////////////////////////////////////////
// class CPort
WORD sl_port_inputPortData(volatile st_port *port) 
{ 
	return port->DR; 
}
void sl_port_outputPortData(volatile st_port *port, WORD data) 
{
	port->DR = data; 
}
WORD sl_port_getOutPortputData(volatile st_port *port) 
{ 
	return port->DR; 
}
LEVEL sl_port_getOutputPinData(volatile st_port *port, unsigned char pin) 
{ 
	return sl_port_inputPinData(port, pin); 
}
WORD sl_port_getPortDirection(volatile st_port *port) 
{ 
	return port->IOR; 
}
void sl_port_setPortDirection(volatile st_port *port, WORD direction) 
{ 
	port->IOR = direction; 
}
void sl_port_setPortDR(volatile st_port *port, WORD direction)
{
	port->DR=direction;
}
WORD sl_port_getPortMode(volatile st_port *port) 
{
	return port->_cr.CR;
}
WORD sl_port_getPortMode1(volatile st_port *port) 
{
	return port->_cr.CR1; 
}
WORD sl_port_getPortMode2(volatile st_port *port) 
{
	return port->CR2; 
}
void sl_port_setPortMode(volatile st_port *port,WORD mode) 
{ 
	port->_cr.CR=mode; 
}
void sl_port_setPortMode1(volatile st_port *port,WORD mode) 
{
	port->_cr.CR1= mode;
}
void sl_port_setPortMode2(volatile st_port *port,WORD mode) 
{
	port->CR2= mode; 
}

LEVEL sl_port_inputPinData(volatile st_port *port,unsigned char pin)
{//	volatile st_port *m_pPort;
    volatile st_port *m_pPort;
	m_pPort=port;
	if(pin<16)
		return ((m_pPort->DR)&(1<<pin))?HIGHLEVEL:LOWLEVEL;
	else
		return LOWLEVEL;
}

void sl_port_outputPinData(volatile st_port *port, unsigned char pin, LEVEL data)
{
//	volatile st_port *m_pPort = port;
volatile st_port *m_pPort;
	m_pPort=port;
	if (pin < 16)
	{
		WORD wOldData = m_pPort->DR;
		WORD wMask = 1 << pin;
		if (data == HIGHLEVEL)
			m_pPort->DR = wOldData | wMask;
		else if (data == LOWLEVEL)
			m_pPort->DR = wOldData & (~wMask);
	}
}

IODirection sl_port_getPinDirection(volatile st_port *port, unsigned char pin)
{
	volatile st_port *m_pPort;
	m_pPort=port;

	if (pin < 16)
		return (m_pPort->IOR & (1 << pin)) ? IOD_OUTPUT : IOD_INPUT;
	else
		return IOD_INPUT;
}

void sl_port_setPinDirection(volatile st_port *port, unsigned char pin, IODirection direction)
{
//	volatile st_port *m_pPort = port;
volatile st_port *m_pPort;
	m_pPort=port;

	if (pin < 16)
	{
		WORD wOldData = m_pPort->IOR;
		WORD wMask = 1 << pin;
		if (direction == IOD_OUTPUT)
			m_pPort->IOR = wOldData | wMask;
		else if (direction == IOD_INPUT)
			m_pPort->IOR = wOldData & (~wMask);
	}
}


////////////////////////////////////////////////////////////////////////////////
// class CPortA
st_port * sl_port_getPortA(void)
{ volatile st_port *pPort = (volatile st_port *)&PA;
	return pPort;
}

int sl_portA_getPinMode(volatile st_port *port, unsigned char pin)
{
 	volatile st_port *m_pPort;

	if(pin < 16)
		return ((m_pPort->_cr.CR)&(1<<pin))?PIN_MODE_OTHER:PIN_MODE_IO;
	else
		return PIN_MODE_ERROR;
}

void sl_portA_setPinMode(volatile st_port *port, unsigned char pin, int mode)
{
	volatile st_port *m_pPort;
     WORD wOldData;
	 WORD wMask;
	if (pin < 16)
	{
		wOldData=m_pPort->_cr.CR;
		wMask =1<<pin;
		if(mode==PIN_MODE_OTHER)
			m_pPort->_cr.CR=wOldData|wMask;
		else if(mode==PIN_MODE_IO)
			m_pPort->_cr.CR=wOldData&(~wMask);
	}
}




////////////////////////////////////////////////////////////////////////////////
// class CPortB

st_port * sl_port_getPortB()
{  volatile st_port *pPort = (volatile st_port *)&PB;
	return pPort;
}

LEVEL sl_portB_inputPinData(volatile st_port *port, unsigned char pin)
{
//	volatile st_port *m_pPort;

	if(pin<6)
		return sl_port_inputPinData(port,pin);
	else if(pin<12)
		return sl_port_inputPinData(port,pin+2);
	else
		return LOWLEVEL;
}

LEVEL sl_portB_outputPinData(volatile st_port *port,  unsigned char pin, LEVEL data)		
{
	if (pin < 6)
		sl_port_outputPinData(port, pin, data);
	else if (pin < 12)
		sl_port_outputPinData(port, pin + 2, data);
}

LEVEL sl_portB_getOutputPinData(volatile st_port *port,  unsigned char pin)
{
	return sl_portB_inputPinData(port, pin); 
}

IODirection sl_portB_getPinDirection(volatile st_port *port,  unsigned char pin)
{
	if (pin < 6)
		return sl_port_getPinDirection(port, pin);
	else if (pin < 12)
		return sl_port_getPinDirection(port, pin + 2);
	else
		return IOD_INPUT;
}

void sl_portB_setPinDirection(volatile st_port *port,  unsigned char pin, IODirection direction)
{
	if (pin < 6)
		sl_port_setPinDirection(port, pin, direction);
	else if (pin < 12)
		sl_port_setPinDirection(port, pin + 2, direction);
}

int sl_portB_getPinMode(volatile st_port *port,  unsigned char pin)
{
	if (pin < 6)
		return sl_portA_getPinMode(port, pin);
	else if (pin < 11)
		return sl_portA_getPinMode(port, pin + 2);
	else if (pin == 12)
		return ((volatile struct st_pb *)port)->CR.BIT.MD11;
	else
		return PIN_MODE_ERROR;
}

void sl_portB_setPinMode(volatile st_port *port,  unsigned char pin, int mode)
{
	if (pin < 6)
		sl_portA_setPinMode(port, pin, mode);
	else if (pin < 11)
		sl_portA_setPinMode(port, pin + 2, mode);
	else if (pin == 12)
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_B11_MODE_A21) || (mode == PIN_B11_MODE_POD))
			((volatile struct st_pb *)port)->CR.BIT.MD11 = mode;
	}
}


////////////////////////////////////////////////////////////////////////////////
// class CPortC

st_port * sl_port_getPortC()
{
	volatile st_port *pPort=(volatile st_port *)&PC;

	return pPort;
}

int sl_portC_getPinMode(volatile st_port *port,  unsigned char pin)
{
	volatile st_port *m_pPort = port;
	
	if(pin<6)
		return (m_pPort->CR2&(1<<(pin<<2)))?PIN_MODE_OTHER:PIN_MODE_IO;
	else if(pin<8)
		return (m_pPort->CR2)>>(((pin ==6)?12:14))&3;
	else if(pin<15)
		return (m_pPort->_cr.CR1)>>((pin-8)<<2)&3;
	else
		return PIN_MODE_ERROR;
}

void sl_portC_setPinMode(volatile st_port *port, unsigned char pin, int mode)
{
	WORD wMask;
	WORD wNewData;
	volatile st_port *m_pPort = port;

	if (pin < 6)
	{
		if ((mode == PIN_MODE_IO) && (mode == PIN_MODE_OTHER))
		{
			wMask = pin << 2;
			wNewData = mode << wMask;
			wMask = 1 << wMask;
		}
		else
			return;
	}
	else if (pin == 6)
	{
		if ((mode >= 0) && (mode <= 3))
		{
			wMask = 0x30;
			wNewData = mode << 12;
		}
		else
			return;
	}
	else if (pin == 7)
	{
		if ((mode == PIN_MODE_IO) && (mode == PIN_MODE_OTHER))
		{
			wMask = 0xc0;
			wNewData = mode << 14;
		}
		else
			return;
	}
	else if (pin < 15)
	{
		if ((pin == 11) || (pin == 12))
		{
			if ((mode < 0) || (mode > 2))
				return;
		}
		else if ((mode != PIN_MODE_IO) && (mode != PIN_MODE_OTHER))
			return;
		wMask = (pin - 8) << 2;
		wNewData = mode << wMask;
		wMask = 3 << wMask;
	}
	else
		return;

	if(pin<8)
		m_pPort->CR2=(m_pPort->CR2&(~wMask))|wNewData;
	else
		m_pPort->_cr.CR1=(m_pPort->_cr.CR1)&(~wMask)|wNewData;
}

void sl_portC_outputPinData(volatile st_port *port,  unsigned char pin, LEVEL data)		
{
	if (pin < 15)
		sl_port_outputPinData(port, pin, data);
	
}

////////////////////////////////////////////////////////////////////////////////
// class CPortD
st_port * sl_port_getPortD()
{
	volatile st_port *pPort = (volatile st_port *)&PD;

	return pPort;
}

int sl_portD_getPinMode(volatile st_port *port, unsigned char pin) 
{
	return sl_portA_getPinMode(port, pin);
}
void sl_portD_setPinMode(volatile st_port *port, unsigned char pin, int mode)
{ 
	sl_portA_setPinMode(port, pin, mode); 
}


////////////////////////////////////////////////////////////////////////////////
// class CPortE

st_port * sl_port_getPortE()
{
	volatile st_port *pPort = (volatile st_port *)&PE;

	return pPort;
}


int sl_portE_getPinMode(volatile st_port *port, unsigned char pin)
{
	volatile st_port *m_pPort = port;

	if (pin < 15)
		return sl_portA_getPinMode(port, pin);
	else
		return PIN_MODE_ERROR;
}

void sl_portE_setPinMode(volatile st_port *port, unsigned char pin, int mode)
{
	volatile st_port *m_pPort = port;

	if (pin < 15)
		sl_portA_setPinMode(port, pin, mode);
}

void  sl_portE_outputPinData(volatile st_port *port,  unsigned char pin, LEVEL data)		
{
	if (pin <15)
		sl_port_outputPinData(port, pin, data);

}
////////////////////////////////////////////////////////////////////////////////
// class CPortF

st_port * sl_port_getPortF()
{
	volatile st_port *pPort = (volatile st_port *)&PF;

	return pPort;
}

int sl_portF_getPinMode(volatile st_port *port, unsigned char pin)
{
 	volatile st_port *m_pPort = port;

	if (pin<4)
		return (m_pPort->CR2&(1<<(pin<<2)))?PIN_MODE_OTHER:PIN_MODE_IO;
	else if (pin<8)
		return (m_pPort->CR2>>(8 +((pin -4)<<2)))&3;
	else if (pin < 12)
		return (m_pPort->_cr.CR1)>>((pin-8)<<2)&3;
	else
		return PIN_MODE_ERROR;
}

void  sl_portF_setPinMode(volatile st_port *port, unsigned char pin, int mode)
{
	WORD wMask;
	WORD wNewData;
	volatile st_port *m_pPort = port;

	if (pin < 4)
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_MODE_OTHER))	

		{
			wMask = pin << 2;
			wNewData = mode << wMask;
			wMask = 1 << wMask;
		}
		else
			return;
	}
	else if ((pin > 3) && (pin < 8))
	{
		if ((mode >= 0) && (mode < 3))
		{
			wMask = pin << 2;
			wNewData = mode << wMask;
			wMask = 3 << wMask;
		}
		else
			return;
	}
	else if (pin < 12)
	{
	
		if (pin == 9)
		{
			if ((mode < 0) || (mode > 3))
				return;
		}
		else if ((mode < 0) || (mode > 2))
			return;
	
		wMask = (pin - 8) << 2;
		wNewData = mode << wMask;
		wMask = 3 << wMask;
	}
	else
		return;

	if(pin < 8)
		(m_pPort->CR2)=(m_pPort->CR2)&(~wMask)|wNewData;
	else
		(m_pPort->_cr.CR1)=(m_pPort->_cr.CR1)&(~wMask)|wNewData;
}

void  sl_portF_outputPinData(volatile st_port *port,  unsigned char pin, LEVEL data)		
{
	if (pin < 12)
		sl_port_outputPinData(port, pin, data);
}
////////////////////////////////////////////////////////////////////////////////
// class CPortG

st_port * sl_port_getPortG()
{
	volatile st_port *pPort = (volatile st_port *)&PG;

	return pPort;
}

WORD  sl_portG_getPinMode(volatile st_port *port, unsigned char pin)
{
	volatile st_port *m_pPort = port;

	if(pin==0)
		return (m_pPort->CR2<<2)&3;
	else if(pin==1)
		return (m_pPort->CR2<<4)&1;
	else if(pin==2)
		return (m_pPort->CR2<<5)&1;
	else if(pin<8)
		return (m_pPort->CR2)&(1<<(pin<<2))?PIN_MODE_OTHER:PIN_MODE_IO;
	else if(pin<14)
        return (m_pPort->_cr.CR1&(1<<((pin-8)<<2)))?PIN_MODE_OTHER:PIN_MODE_IO;
	else if(pin<16)
		return m_pPort->_cr.CR1>>((pin-8)<<2)&3;
	else
		return PIN_MODE_ERROR;
}

void  sl_portG_setPinMode(volatile st_port *port, unsigned char pin, int mode)
{
	WORD wMask;
	WORD wNewData;
	volatile st_port *m_pPort = port;

	if (pin == 0)
	{
		if ((mode >= 0) && (mode < 3))
		{
			wMask = 0x000c;
			wNewData = mode << 2;
		}
		else
			return;
	}
	if (pin == 1)
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_MODE_OTHER))
		{
			wMask = 0x0010;
			wNewData = mode << 4;
		}
		else
			return;
	}
	if (pin == 2)
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_MODE_OTHER))
		{
			wMask = 0x0020;
			wNewData = mode << 5;
		}
		else
			return;
	}
	if (pin < 4)
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_MODE_OTHER))
		{
			wMask = pin << 2;
			wNewData = mode << wMask;
			wMask = 1 << wMask;
		}
		else
			return;
	}
	else if ((pin >= 3) && (pin < 8))
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_MODE_OTHER))
		{
			wMask = pin << 2;
			wNewData = mode << wMask;
			wMask = 1 << wMask;
		}
		else
			return;
	}
	else if (pin < 14)
	{
		if ((mode == PIN_MODE_IO) || (mode == PIN_MODE_OTHER))
		{
			wMask = (pin - 8) << 2;
			wNewData = mode << wMask;
			wMask = 1 << wMask;
		}
		else
			return;
	}
	else if(pin<16)
	{
		if((mode >= 0)&&(mode<3))
		{
			wMask=(pin-8)<<2;
			wNewData =mode<< wMask;
			wMask = 3 << wMask;
		}
		else
			return;
	}
	else
		return;

	if(pin<8)
		m_pPort->CR2=(m_pPort->CR2&(~wMask))|wNewData;
	else
		m_pPort->_cr.CR1=(m_pPort->_cr.CR1&(~wMask))|wNewData;
}

int  sl_portG_getPin159ModeFor(volatile st_port *port)
{
	return port->CR2 & 3;
}

void  sl_portG_setPin159Mode(volatile st_port *port, int mode)
{
	if ((mode == PIN_159_MODE_HIGH) || (mode == PIN_159_MODE_IRQOUT))
		((volatile struct st_pg *)port)->CR.BIT.IRQMD = mode;
}

void  sl_portG_outputPinData(volatile st_port *port,  unsigned char pin, LEVEL data)		
{
	if (pin < 16)
		sl_port_outputPinData(port, pin, data);
}
////////////////////////////////////////////////////////////////////////////////
// class CPortH

st_port * sl_port_getPortH()
{
	volatile st_port *pPort = (volatile st_port *)&PH;

	return pPort;
}

void sl_portH_outputPortData(volatile st_port *port, WORD data) 
{
}
WORD sl_portH_getOutPortputData(volatile st_port *port) 
{
	return 0; 
}
void sl_portH_outputPinData(volatile st_port *port, unsigned char pin, LEVEL data) 
{
}

LEVEL sl_portH_getOutputPinData(volatile st_port *port, unsigned char pin) 
{
	return LOWLEVEL; 
}

WORD sl_portH_getPortDirection(volatile st_port *port) 
{
	return 0; 
}
void sl_portH_setPortDirection(volatile st_port *port, WORD direction) 
{
}

IODirection sl_portH_getPinDirection(volatile st_port *port, unsigned char pin) 
{
	return IOD_INPUT;
}
void sl_portH_setPinDirection(volatile st_port *port, unsigned char pin, IODirection direction) 
{
}

WORD sl_portH_getPortMode(volatile st_port *port) 
{
	return 0;
}

WORD sl_portH_getPortMode1(volatile st_port *port) 
{
	return 0; 
}
WORD sl_portH_getPortMode2(volatile st_port *port) 
{
	return 0; 
}
void sl_portH_setPortMode(volatile st_port *port, WORD mode) 
{
}
void sl_portH_setPortMode1(volatile st_port *port, WORD mode) 
{
}
void sl_portH_setPortMode2(volatile st_port *port, WORD mode) 
{
}

int sl_portH_getPinMode(volatile st_port *port, unsigned char pin) 
{
	return PIN_MODE_ERROR; 
}
void sl_portH_setPinMode(volatile st_port *port, unsigned char pin, int mode) 
{
}
